package cn.wolfcode.business.service.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import cn.wolfcode.business.domain.BusAppointment;
import cn.wolfcode.business.domain.BusStatement;
import cn.wolfcode.business.domain.vo.StatementItemVO;
import cn.wolfcode.business.service.IBusAppointmentService;
import cn.wolfcode.business.service.IBusStatementService;
import cn.wolfcode.common.core.domain.model.LoginUser;
import cn.wolfcode.common.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.wolfcode.business.mapper.BusStatementItemMapper;
import cn.wolfcode.business.domain.BusStatementItem;
import cn.wolfcode.business.service.IBusStatementItemService;
import org.springframework.transaction.annotation.Transactional;


@Service
public class BusStatementItemServiceImpl implements IBusStatementItemService {
    @Autowired
    private BusStatementItemMapper busStatementItemMapper;  //结算单明细Mapper
    @Autowired
    private IBusStatementService statementService;  //结算单Mapper
    @Autowired
    private IBusAppointmentService appointmentService;  //预约单详情Service

    //保存功能代码实现
    @Transactional  //事务
    @Override
    public int insertBusStatementItem(StatementItemVO vo) {
        //数据校验
        if (vo == null || vo.getDiscountPrices() == null || vo.getStatementItemList() == null || vo.getStatementItemList().size() == 0) {
            throw new RuntimeException("参数异常");
        }

        //在结算单明细中拿到第一条数据中的statementID  作为我们结算单ID
        Long statementId = vo.getStatementItemList().get(0).getStatementId();
        // 根据收到的结算单 ID 去查询结算单对象
        BusStatement statement = statementService.selectBusStatementById(statementId);
        //对查询的对象进行验证
        if (statement == null) {
            throw new RuntimeException("结算单不存在");
        }
        //判断结算单状态，必须是消费中才能进行保存
        if (!BusStatement.STATUS_CONSUME.equals(statement.getStatus())) {
            throw new RuntimeException("状态不是消费中，不能进行保存");
        }
        //删除旧的当前结算单对应的结算单明细数据
        busStatementItemMapper.deleteRelationStatementItemByStatementId(statementId);

        //总价格
        BigDecimal totalAmount = new BigDecimal(0);
        //总数量
        BigDecimal totalQuantity = new BigDecimal(0);
        //总折扣
        BigDecimal discountAmount = vo.getDiscountPrices();
        //循环遍历我们的结算单明细结合  总价格和总数量
        for (BusStatementItem item : vo.getStatementItemList()) {
            // 计算总价格
            totalAmount = totalAmount.add(item.getItemPrice().multiply(new BigDecimal(item.getItemQuantity())));

            // 计算总数量
            totalQuantity = totalQuantity.add(new BigDecimal(item.getItemQuantity()));
        }

        //验证总价格和总数量

        //总价格>=0 && 折扣价>=0 && 总价格>=折扣价
        // 正确的格式
        if (!(totalAmount.compareTo(new BigDecimal(0)) >= 0
                && discountAmount.compareTo(new BigDecimal(0)) >= 0
                && totalAmount.compareTo(discountAmount) >= 0)) {
            throw new RuntimeException("总价格大于0，且优惠价大于0，且总价要大于折扣价");
        }
        //验证总数量大于0
        if (totalQuantity.compareTo(new BigDecimal(0)) <= 0) {
            throw new RuntimeException("总数量必须大于0");
        }
        //更新结算单
        statementService.updateAmount(statementId, totalAmount, totalQuantity, discountAmount);
        // 批量插入结算单明细

        return busStatementItemMapper.insertBusStatementItemBatch(vo.getStatementItemList());
    }

    //查询功能代码实现
    @Override
    public List<BusStatementItem> getStatementItemList(Long statementId) {
        BusStatementItem statementItem = new BusStatementItem();
        statementItem.setStatementId(statementId);
        return busStatementItemMapper.selectBusStatementItemList(statementItem);
    }

    //支付功能代码实现
    @Transactional
    @Override
    public int pay(Long statementId) {
        //参数合理化验证
        if (statementId == null) {
            throw new RuntimeException("参数错误");
        }
        //根据结算单ID 查询结算单对象
        BusStatement statement = statementService.selectBusStatementById(statementId);
        if (statement == null) {
            throw new RuntimeException("结算单不存在");
        }
        // 验证结算单状态是消费中才可以支付操作
        if (BusStatement.STATUS_PAID.equals(statement.getStatus())) {
            throw new RuntimeException("只有消费的结算单才能支付操作");
        }

        //判断结算单是否由预约单生成 如果是，则不能支付
        if (statement.getAppointmentId() != null) {
        //存在预约iD 说明是预约用户 则不能支付
            appointmentService.updateStatus(statement.getAppointmentId(), BusAppointment.STATUS_PAID);

        }
        //根据结算单ID修改结算单的状态为已支付，同时添加收款人和时间
        Long payId = SecurityUtils.getUserId();
        return statementService.updatePayStatus(statementId, payId, new Date(), BusStatement.STATUS_PAID);


    }

}